<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of UsersController
 *
 * @author Poh Nean
 */
class UsersController extends PsController
{

	public $layout = 'manage';

	public function accessRules()
	{
		return CMap::mergeArray(array(
					array('allow',
						'actions' => array('index', 'ajaxGetOverridings', 'ajaxLoadPrevailingDesignations', 'geneology', 'view'),
						'roles' => array('ManageAgency.User.View'),
					),
					array('allow',
						'actions' => array('ajaxSearchCEADatabase', 'ajaxDeletePromotion',  'ajaxDeleteScoreAdjustement', 'adduser', 'adduserSuccess', 'promote', 'update', 'adjustScore', 'impersonate', 'commission', 'bankinfo', 'resetpw', 'traininginfo'),
						'roles' => array('ManageAgency.User.Manage'),
					),
						), parent::accessRules());
	}

	public function actionIndex($action = null)
	{
		if ($_GET['action'] == 'Clear Filters') {
			$this->redirect(array('/manage/users/index'));
		}

		$user = new User('search');
		$user->unsetAttributes();
		if (isset($_GET['User'])) {
			$user->attributes = $_GET['User'];
			$user->designation_id = $_GET["User"]["designation_id"];
			$user->auth_item_name = $_GET["User"]["auth_item_name"];
			$user->last_login_option = $_GET["User"]["last_login_option"];
		}

		$pagesize = 50; // default pagesize
		if (isset($_GET['pagesize'])) {
			$pagesize = $_SESSION['manage_users_gridview_pagesize'] = $_GET['pagesize'];
		} else if (isset($_SESSION['manage_users_gridview_pagesize'])) {
			$pagesize = $_SESSION['manage_users_gridview_pagesize'];
		}

		$dataProvider = $this->getDataProvider($user, $pagesize);

		if ($action == 'Export') {
			$criteria = $dataProvider->getCriteria();
			$criteria->select = array(
				'@curRow := @curRow + 1 AS No',
				't.username as Username',
				't.name as Name',
				't.display_name as "Display Name"',
				't.license_no as "License No."',
				'pr.name AS "Designation"',
				'pr.abbreviation AS "Designation (Abbr)"',
				't.email as "Email"',
				't.mobile as "Mobile"',
				't.landline as "Landline"',
				'GROUP_CONCAT(userAuthItem.description) as "Roles"',
				't2.name AS "Upline"',
				't.last_login AS "Last Login"'
			);
			$criteria->join .= 'INNER JOIN (SELECT @curRow := 0) r ';
			$criteria->join .= 'LEFT JOIN user_auth_assignment userAuthAssignments ON (userAuthAssignments.userid = t.id) ';
			$criteria->join .= 'LEFT JOIN user_auth_item userAuthItem ON (userAuthAssignments.itemname = userAuthItem.name) ';
			$criteria->join .= 'LEFT JOIN `user` t2 ON (t.upline_user_id = t2.id) ';
			$criteria->group = 't.id';
			$command = Yii::app()->db->commandBuilder->createFindCommand('user', $criteria);

			Yii::import('common.lib.ECSVExport');
			$csv = new ECSVExport($command, FALSE);
			$content = $csv->toCSV();
			Yii::app()->getRequest()->sendFile('users_' . time() . '.csv', $content, "text/csv", true);
			Yii::app()->end();
		}

		$data = array();
		$data['user'] = $user;
		$data['dataProvider'] = $dataProvider;

		$this->render('index', $data);
	}

	public function actionGeneology()
	{
		$tree = $this->getTree();

		$data = array();
		$data['json'] = json_encode($tree);

		$this->render('geneology', $data);
	}

	public function actionAdduser()
	{
		$user = new User;
		$user->agency_id = Yii::app()->user->getSelectedAgencyId();
		$user->setScenario('adminadduser');

		if (!empty($_POST['User'])) {
			// Make sure the admin can only add/modify agents from their own agency
			if (!empty($_POST['User']['license_no'])) {
//				$user = PsCEADataGrabber::grabAgent($_POST['User']['license_no']);
				$user = User::model()->findByAttributes(array('license_no' => $_POST['User']['license_no']));

				if ($user == null) {
					PsSystemMessage::add('Invalid CEA license no', 'error', false);
					$this->refresh();
				} else if ($user instanceof User) {
					if ($user->agency_id != Yii::app()->user->getSelectedAgencyId()) {
						PsSystemMessage::add('User does not belong to ' . Yii::app()->user->getSelectedAgency()->name, 'error', false);
						$this->refresh();
					} else if ($user->activate_date != null) {
						PsSystemMessage::add('User is already activated', 'error', false);
						$this->refresh();
					} else {
						// valid user, continue
						$user->setScenario('adminadduser');
					}
				}
			}

			$user->attributes = $_POST['User'];

			$attributes = array(
				'name',
				'mobile',
				'email',
				'nric',
				'username',
				'password',
				'license_no',
				'agency_id',
			);

			$isValid = $user->validate($attributes);

			if ($isValid) {
				$tx = Yii::app()->db->beginTransaction();
				try {
					if ($user->isNewRecord) {
						$party = new Party();
						$party->type = 'User';
						$party->save();

						$user->party_id = $party->id;
					}

					if ($user->status != User::STATUS_ACTIVE) {
						// activate account
						$user->status = User::STATUS_ACTIVE;

						if ($user->activate_date == null) {
							$user->activate_date = new CDbExpression('UTC_TIMESTAMP()');
						}
					}

					$success = $user->saveNode(false);

					if ($success) {
						$user->setup();
						// assign roles
						if (!empty($_POST['User']['userAuthItems'])) {
							foreach ($_POST['User']['userAuthItems'] as $itemname) {
								// check authassign already exists for agent not actived
								$authAssignment = UserAuthAssignment::model()->findByAttributes(array(
									'userid' => $user->id,
									'itemname' => $itemname
										));

								if (!isset($authAssignment)) {
									$authAssignment = new UserAuthAssignment;
									$authAssignment->itemname = $itemname;
									$authAssignment->userid = $user->id;
									$authAssignment->save(false);
								}
							}
						}

						$password = $_POST['User']['password'];

						// send activation email
						if ($_POST["sendEmail"] == '1' && !empty($user->email)) {
							// send welcome email
							if ($user->sendAgencyWelcomeEmail($password)) {
								PsSystemMessage::add('Welcome email sent to ' . $user->email . '.', 'success');
							}

							$user->sendActivationNotificationToAdmin();
						}
						if ($_POST["sendSMS"] == '1' && !empty($user->mobile)) {
							// send welcome sms
							if ($user->sendAgencyWelcomeSMS($password)) {
								PsSystemMessage::add('Welcome sms sent to ' . $user->mobile . '.', 'success');
							}
						}

						PsSystemMessage::add('User created.', 'success');
						$tx->commit();

						$data = array();
						$data['password'] = $password;
						$data['user'] = $user;
						$this->render('adduser_success', $data);

						Yii::app()->end();
					}
				} catch (CDbException $e) {
					$tx->rollback();
//					dump($e);
				}
			}
		}

		$data = array();
		$data['user'] = $user;
		$this->render('adduser', $data);
	}

	public function actionUpdate($id, $action = null)
	{
		$user = $this->loadUser($id);
		$user->setScenario('updateprofile');
		$authManager = Yii::app()->authManager;

		if ($action == 'RemoveImage') {
			// delete user profile image
			if (!empty($user->photo)) {
				if ($user->removePhoto()) {
					PsSystemMessage::add('Profile image removed.', 'success');
					$this->redirect(array('/' . $this->route, 'id' => $id));
				} else {
					PsSystemMessage::add('There was a problem removing your profile image. Please try again', 'failure');
				}
			}
		}

		if (isset($_POST['User'])) {
			// do same update profile calEvent  
			$user->attributes = $_POST['User'];
			$user->custom = $_POST['User']['custom'];

			$upload = CUploadedFile::getInstance($user, 'photo');

			if ($user->validate()) {
				$tx = Yii::app()->db->beginTransaction();
				$success = true;

				try {
					// save uploaded photo, if any
					if ($upload != null) {
						$success = $user->savePhoto($upload);
						if (!$success) {
							PsSystemMessage::add("Error uploading image.", "failure");
						}
					}

					$success = $user->saveNode(false) && $success;

					if (!empty($_POST['roles'])) {
						foreach ($_POST['roles'] as $roleName => $roleEnabled) {
							if ($roleEnabled == '1') {
								if (!$authManager->isAssigned($roleName, $user->id)) {
									$auth = $authManager->assign($roleName, $user->id);
									$success = !empty($auth) && $success;
								}
							} else {
								if ($authManager->isAssigned($roleName, $user->id)) {
									$success = $authManager->revoke($roleName, $user->id) && $success;
								}
							}
						}
					}

					// Save user model
					if ($success) {
						$tx->commit();
						PsSystemMessage::add('Profile Updated.', 'success');
						$this->refresh();
					} else {
						PsSystemMessage::add('There was a problem updating your profile. Please try again', 'failure');
					}
				} catch (CDbException $e) {
					$tx->rollback();
//					dump($e);
				}
			} else {
//				dump($user->getErrors());
			}
		}


		// Custom fields without groups
		$customFields = CustomField::model()->findAllByAttributes(array(
			'agency_id' => $user->agency_id,
			'custom_field_model' => 'User',
			'custom_field_group_id' => null
				), array('order' => 'pos'));

		// Custom Field groups
		$customFieldGroups = CustomFieldGroup::model()->findAllByAttributes(array(
			'agency_id' => $user->agency_id,
			'custom_field_model' => 'User'
				), array('order' => 'pos'));

		$data = array();
		$data['user'] = $user;
		$data['customFields'] = $customFields;
		$data['customFieldGroups'] = $customFieldGroups;
		$data['roles'] = $authManager->getRoles();
		$data['authManager'] = $authManager;

		$this->render('update', $data);
	}

	public function actionAdjustScore($id)
	{
		$user = $this->loadUser($id);

		$scoreAdjustment = new ScoreAdjustment;
		$scoreAdjustment->agency_id = $user->agency_id;
		$scoreAdjustment->user_id = $id;
		$scoreAdjustment->adjusted_by_user_id = Yii::app()->user->id;

		if (isset($_POST['ScoreAdjustment'])) {
			$scoreAdjustment->attributes = $_POST['ScoreAdjustment'];
			$scoreAdjustment->create_time = new CDbExpression('UTC_TIMESTAMP()');


			$adjustTimeSubmitted = $_POST['ScoreAdjustment']['adjustment_effect_time'];
			$adjustTimeArray = explode(' ', $adjustTimeSubmitted);
			$adjustDate = $adjustTimeArray[0];
			$adjustDateParts = explode('-', $adjustDate);
			$adjustDateFormatted = $adjustDateParts[2] . '-' . $adjustDateParts[1] . '-' . $adjustDateParts[0];
			$adjustTime = $adjustTimeArray[1] . ':00';
			$scoreAdjustment->adjustment_effect_time = $adjustDateFormatted . ' ' . $adjustTime;

			if ($scoreAdjustment->save()) {
				PsSystemMessage::add('User adjustment created.', 'success');
				$this->redirect(array('users/commission', 'id' => $id));
			} else {
//				dump($scoreAdjustment->getErrors());
			}
		}

		Yii::import('common.widgets.CJuiDateTimePicker.CJuiDateTimePicker');
		$data = array();
		$data['user'] = $user;
		$data['scoreAdjustment'] = $scoreAdjustment;

		$this->render('adjustScore', $data);
	}

	public function actionPromote($id, $date = null, $desigId = null, $receiptId = null)
	{
		$user = $this->loadUser($id);
		$latestDesignation = $user->promotions(array('sort' => 'from_date DESC', 'limit' => 1));
		$promotion = new Promotion;

		$cumulativePolicy = Yii::app()->user->model->agency->settings['Commission']['Policies']['CumulativeAmountsForScore'];
		$cumulativePolicy = !empty($cumulativePolicy) ? $cumulativePolicy : "Paid";

		if (isset($_POST['Promotion']) || (!is_null($desigId) && !is_null($receiptId))) {
			$promotion = new Promotion;
			$promotion->from_date = isset($_POST['Promotion']) ? $_POST['Promotion'][from_date] : $date;
			$promotion->designation_id = isset($_POST['Promotion']) ? $_POST['Promotion']['designation_id'] : $desigId;
			$promotion->comments = isset($_POST['Promotion']) ? $_POST['Promotion']['comments'] : '';
			$promotion->promoted_by = Yii::app()->user->id;
			$promotion->promoted_time = new CDbExpression('UTC_TIMESTAMP()');
			$promotion->promotion_type = 'manual';
			$promotion->user_id = $id;
			$newPos = $promotion->designation->pos;
			$previousPos = $user->getLastPromotion($promotion->from_date)->designation->pos;
			if ($promotion->save()) {
				$newDesignationScores = $promotion->designation->designationCriterias;
				$achievedScores = array();
				$adjustmentAmounts = array();
				if (!empty($newDesignationScores)) {
					foreach ($newDesignationScores as $newDesignationScore) {
						$criteriaAmount = $newDesignationScore->amount;
						$criteriaTypeCode = $newDesignationScore->criteria_type_code;
						switch ($criteriaTypeCode) {
							case 'gross_comm':
							case 'net_comm':
								switch ($cumulativePolicy) {
									case "Paid":
										$achievedScore = $user->getTotalScoreCommsReceived($promotion->from_date, $criteriaTypeCode);
										break;
									case "Submitted":
										$achievedScore = $user->getTotalScoreCommsSubmitted($promotion->from_date, $criteriaTypeCode);
										break;
								}
								break;
							case 'units_transacted':
							case 'units_sold':
								$achievedScore = $user->getTotalScoreCasesApproved($promotion->from_date, $criteriaTypeCode);
								break;
						}
						$achievedScores[$criteriaTypeCode] = $achievedScore;
						if ($achievedScore < $criteriaAmount || ($achievedScore <> $criteriaAmount && $newPos < $previousPos)) {
							$adjustmentAmounts[$criteriaTypeCode] = $criteriaAmount - $achievedScore;
						}
					}
				}

//				We subtract scores when we demote, that is, when the pos of the new designation 
//				is less than the pos of the last explicit (higher) designation.
//				The $adjustmentAmount value here is negative.
//				dump($achievedScores);
//				exit;

				if (!empty($adjustmentAmounts)) {
					foreach ($adjustmentAmounts as $criteria_type_code => $amount) {
						if ($amount <> 0) {
							$scoreAdjustment = new ScoreAdjustment;
							$scoreAdjustment->user_id = $id;
							$scoreAdjustment->criteria_type_code = $criteria_type_code;
							$scoreAdjustment->amount = $amount;
							$scoreAdjustment->adjustment_effect_time = $promotion->from_date;
							$scoreAdjustment->adjusted_by_user_id = Yii::app()->user->id;
							$scoreAdjustment->agency_id = $user->agency_id;
							$scoreAdjustment->reason = 'Manual appointment of salesperson to ' . $promotion->designation->name;
							$scoreAdjustment->create_time = new CDbExpression('UTC_TIMESTAMP()');
							$scoreAdjustment->save();
						}
					}
				}
				PsSystemMessage::add('User designation updated.', 'success');
				if (isset($_POST['Promotion'])) {
					$this->redirect(array('users/commission', 'id' => $id));
				} else {
					$this->redirect(array('/receipt/calculateCommissions', 'id' => $receiptId));
				}
			} else {
//				dump($promotion->getErrors());
			}
		}

		$data = array();
		$data['user'] = $user;
		$data['promotion'] = $promotion;
		$data['latestDesignation'] = $latestDesignation;

		$this->render('promote', $data);
	}

	public function actionAjaxLoadPrevailingDesignations()
	{
		$response = array();

		$date = $_POST['date'];

		$criteria = new CDbCriteria;
		$criteria->join = "JOIN `hierarchy` h ON t.hierarchy_id = h.id";

		$where1 = 't.deleted = 0 AND h.agency_id IN (' . implode(',', Yii::app()->user->getSelectedAgency()->getParentAgencyIds()) . ') AND ';
		$where2 = $where1 . "h.from_date <= '" . $date . "' AND (h.to_date >= '" . $date . "' OR h.to_date IS NULL)";

		$criteria->condition = $where2;
		$criteria->order = 't.pos ASC';

		$designations = Designation::model()->findAll($criteria);

		if (!empty($designations)) {
			foreach ($designations as $designation) {
				$desigs[$designation->id] = $designation->name;
				$pos[] = $designation->id;
			}
			$response["result"] = 'success';
			$response["designations"] = $desigs;
			$response["pos"] = $pos;
		} else {
			$response["result"] = 'failure';
			$response["errorMsg"] = 'No available designations';
		}

		print json_encode($response);
	}

	public function actionView($id)
	{
		$user = $this->loadUser($id);
		$promotions = $user->promotions(array('order' => 'from_date ASC'));

		$data = array();
		$data['user'] = $user;
		$data['promotions'] = $promotions;

		$this->render('view', $data);
	}

	public function getDataProvider(User $user, $pagesize = 50)
	{
		$criteria = new CDbCriteria;
		$criteria->together = true;

		$criteria->addInCondition('t.agency_id', Yii::app()->user->getSelectedAgency()->getChildAgencyIds());
		$criteria->compare('t.name', $user->name, true);
		$criteria->compare('t.username', $user->username, true);
		$criteria->compare('t.mobile', $user->mobile, true);
		$criteria->compare('t.status', User::STATUS_ACTIVE);
		$criteria->join .= 'LEFT JOIN (SELECT MAX(promoted_time) AS last_promoted_time, p.user_id, p.designation_id, d.name, d.abbreviation '
				. 'FROM `promotion` p INNER JOIN user u ON (p.user_id = u.id) '
				. 'INNER JOIN `designation` d ON (p.designation_id = d.id)'
//				. 'WHERE u.agency_id = :agency_id '
				. 'WHERE u.agency_id IN (' . implode(',', Yii::app()->user->getSelectedAgency()->getChildAgencyIds()) . ') '
				. 'GROUP BY user_id) AS pr ON (pr.user_id = t.id) ';

		if (!empty($user->agencyTeamName)) {
			$criteria->with = array('agencyTeam');
			$criteria->compare('agencyTeam.name', $user->agencyTeamName, true);
		}

		if (!empty($user->designation_id)) {
			$criteria->compare('pr.designation_id', $user->designation_id);
		}

		if (!empty($user->auth_item_name)) {
			$criteria->with[] = 'userAuthAssignments';
			$criteria->compare('userAuthAssignments.itemname', $user->auth_item_name);
		}

		if (!empty($user->upline_user_id)) {
			if ($user->upline_user_id == 'none') {
				$criteria->addCondition('t.upline_user_id IS NULL');
			} else {
				if ($user->include_indirect_uplines == '1') {
					$upline = User::model()->ofCurrentAgency()->findByPk($user->upline_user_id);
					$criteria->compare('t.upline_root_id', $upline->upline_root_id);
					$criteria->compare('t.lft', '>' . $upline->lft);
					$criteria->compare('t.rgt', '<' . $upline->rgt);
				} else {
					$criteria->compare('t.upline_user_id', $user->upline_user_id);
				}
			}
		}


		if (!empty($user->last_login_option)) {
			$time = time();
			$option = strtolower($user->last_login_option);
			switch ($option) {
				case 'never':
					$criteria->addCondition('t.last_login IS NULL');
					break;
				default:
					$temp = strtotime('-' . $user->last_login_option);
					$criteria->compare('t.last_login', ">=" . date('Y-m-d H:m:s', $temp));
					break;
			}
		}

		$sort = new CSort();
		$sort->defaultOrder = 't.name ASC';

		$dataProvider = new CActiveDataProvider('User', array(
					'criteria' => $criteria,
					'pagination' => array(
						'pageSize' => $pagesize,
					),
					'sort' => $sort
				));


		return $dataProvider;
	}

	public function getTreeDataProvider(User $user)
	{
		$criteria = new CDbCriteria;
		$criteria->condition = 't.agency_id = :agency_id';
		$criteria->params = array(
			':agency_id' => Yii::app()->user->model->agency_id
		);
		$criteria->with = array('agencyTeam');

		$criteria->compare('t.name', $user->name, true);
		$criteria->compare('t.username', $user->username, true);
		$criteria->compare('agencyTeam.name', $user->agencyTeamName, true);
		$criteria->compare('t.status', User::STATUS_ACTIVE);

		$criteria->order = 't.upline_root_id DESC, t.lft ASC, t.name ASC';

		$dataProvider = new CActiveDataProvider('User', array(
					'criteria' => $criteria,
					'pagination' => array(
						'pageSize' => (isset($_GET['pagesize']) ? $_GET['pagesize'] : 50),
					)
				));


		return $dataProvider;
	}

	public function actionAjaxGetOverridings()
	{
		$response = array();

		$id = $_POST['id'];

		$tierDetails = array();

		if ($id != null) {
			$response['result'] = 'success';
			$user = $this->loadUser($id);

			$userDetails = array(
				'name' => $user->name,
				'rank' => $user->getEffectiveDesignation()->pos,
				'rank_name' => $user->getEffectiveDesignation()->name ? $user->getEffectiveDesignation()->name : 'No designation'
			);
			$uplines = $user->getAllUplines();

			if (!empty($uplines)) {
				foreach ($uplines as $upline) {
					// check circular reference
					if ($id == $upline->id) {
						$response['errorMsg'] = 'Circular reference detected. You cannot assign ' . $user->name . ' to ' . $upline->name;
						$response['result'] = 'failure';
						break;
					}
					$tierDetails[] = array(
						'name' => $upline->name,
						'rank' => $upline->getEffectiveDesignation()->pos,
						'rank_name' => $upline->getEffectiveDesignation()->name ? $upline->getEffectiveDesignation()->name : 'No designation'
					);
				}
			}
		}
		$response['user'] = $userDetails;
		$response['data'] = $tierDetails;
		print json_encode($response);
	}

	public function actionImpersonate($id = null)
	{
		if (!Yii::app()->user->checkModuleAccess('Propsage.ImpersonateUser')) {
			$this->accessDenied();
		} else {
			$user = $this->loadUser($id);

			$ui = PsUserIdentity::impersonate($user->id);
			if ($ui) {
				$psWebUser = new PsWebUser();
				$psWebUser->allowAutoLogin = true;
				$psWebUser->autoRenewCookie = true;
				$psWebUser->loginUrl = '/account/login';

				$psWebUser->init();

				if ($psWebUser->login($ui, 15 * 60)) {
					$version = $psWebUser->model->version;
					$this->redirect('/' . $version . '/topachiever');
				} else {
					
				}
			}
		}
	}

	public function getTree()
	{
		$tree = array();
		$stack = array();

		$currentUser = Yii::app()->user->model;

		// get data
		$sql = "SELECT t.id, t.name, t.level, t.lft, t.rgt, t.upline_user_id, t.upline_root_id, d.name AS designation_name
			FROM `user` t
			LEFT JOIN `promotion` p ON (t.id = p.user_id)
			LEFT JOIN (SELECT user_id, designation_id, MAX(promoted_time) AS last_promoted_time FROM `promotion` GROUP BY user_id) p2 ON (p.user_id = p2.user_id AND p.promoted_time = p2.last_promoted_time)
			LEFT JOIN `designation` d ON (p.designation_id = d.id)
			WHERE t.agency_id = :agency_id 
			ORDER BY upline_root_id, lft ASC";

		$downlines = Yii::app()->db->createCommand($sql)->queryAll(true, array(
			':agency_id' => Yii::app()->user->getSelectedAgencyId()
				));


		$tree = $this->toHierarchy($downlines);

		$data = array(
			'id' => 'agency',
			'name' => Yii::app()->user->getSelectedAgency()->name,
			'data' => array(),
			'children' => $tree,
		);

		return $data;
	}

	/**
	 * Non-recursive generation of tree array
	 * @param array $collection a nested set array
	 * @return array a hierarchical array
	 */
	public function toHierarchy($collection)
	{
		// Trees mapped
		$tree = array();
		$stackSize = 0;

		if (count($collection) > 0) {
			// Node Stack. Used to help building the hierarchy
			$stack = array();

			foreach ($collection as $node) {
				$item = $node;

				// Number of stack items
				$stackSize = count($stack);

				// Check if we're dealing with different levels
				while ($stackSize > 0 && $stack[$stackSize - 1]['data']['level'] >= $item['level']) {
					array_pop($stack);
					$stackSize--;
				}

				// Stack is empty (we are inspecting the root)
				if ($stackSize == 0) {
					// Assigning the root node
					$i = count($tree);
					$tree[$i]['id'] = $item['id'];
					$tree[$i]['name'] = $item['name'] . '<br/><em>' . $item['designation_name'] . '</em>';
					$tree[$i]['data'] = $item;
					$stack[] = & $tree[$i];
				} else {

					// Add node to parent
					$i = count($stack[$stackSize - 1]['children']);

					$stack[$stackSize - 1]['children'][$i]['id'] = $item['id'];
					$stack[$stackSize - 1]['children'][$i]['name'] = $item['name'] . '<br/><em>' . $item['designation_name'] . '</em>';
					$stack[$stackSize - 1]['children'][$i]['data'] = $item;

					$stack[] = & $stack[$stackSize - 1]['children'][$i];
				}
			}
		}

		return $tree;
	}

	public function actionCommission($id)
	{
		$authManager = Yii::app()->authManager;
		$user = $this->loadUser($id);
		$agency = $user->agency;

		$criteria = new CDbCriteria();
		$criteria->with = array('designation', 'designation.hierarchy');
		$criteria->order = 't.from_date DESC';
		$criteria->compare('t.user_id', $user->id);
		$criteria->compare('t.deleted', 0);

		$promotionsDataProvider = new CActiveDataProvider('Promotion', array(
					'criteria' => $criteria,
					'pagination' => array('pagesize' => 25)
				));

		$criteria = new CDbCriteria();
		$criteria->order = 't.adjustment_effect_time DESC';
		$criteria->compare('t.user_id', $user->id);
		$criteria->compare('t.deleted', 0);
		
		$scoreAdjustmentsDataProvider = new CActiveDataProvider('ScoreAdjustment', array(
					'criteria' => $criteria,
					'pagination' => array('pagesize' => 25)
				));
		
		$allStructures = $agency->getActiveCommissionStructures(date('Y-m-d'));

		$parentStructures = array();
		$ownStructures = array();
		if (!empty($allStructures)) {
			foreach ($allStructures as $structure) {
				if ($structure->agency_id == $agency->id) {
					$ownStructures[] = $structure;
				} else {
					$parentStructures[] = $structure;
				}
			}
		}

		$assignedStructures = $user->commissionStructures;
		$assignedStructureIds = array();
		if (!empty($assignedStructures)) {
			foreach ($assignedStructures as $assignedStructure) {
				$assignedStructureIds[] = $assignedStructure->id;
			}
		}

		if (isset($_POST['User'])) {
			$tx = Yii::app()->db->beginTransaction();

			try {
				$attributes = array(
					'upline_user_id', 'recommender_user_id'
				);

				$user->attributes = $_POST['User'];

				$isValid = $user->validate($attributes);


				if ($isValid) {
					$upline = User::model()->ofCurrentAgency()->findByPk($user->upline_user_id);

					$success = $user->saveNode(false, $attributes);
					if ($upline === null) {
						if (!$user->isRoot()) {
							$user->moveAsRoot();
						}
					} else {
						$user->moveAsLast($upline);
					}

					if ($success) {
						$tx->commit();
						PsSystemMessage::add('User updated.', 'success');
						$this->refresh();
					}
				}
			} catch (CException $e) {
				$tx->rollback();
//					dump($e);
			}
		}

		if (isset($_POST['structureIds'])) {
			$structureIds = $_POST['structureIds'];
			if (!empty($user->userCommissionStructures)) {
				foreach ($user->userCommissionStructures as $userCommissionStructure) {
					$userCommissionStructure->delete();
				}
			}
			if (!empty($structureIds)) {
				$tx = Yii::app()->db->beginTransaction();
				try {
					foreach ($structureIds as $structureId) {
						$userCommissionStructure = new UserCommissionStructure;
						$userCommissionStructure->user_id = $user->id;
						$userCommissionStructure->commission_structure_id = $structureId;
						$userCommissionStructure->update_time = new CDbExpression('UTC_TIMESTAMP()');
						$userCommissionStructure->updated_by_user_id = Yii::app()->user->id;
						$userCommissionStructure->save();
					}
					$tx->commit();
					PsSystemMessage::add('Commission structures assigned', 'success');
				} catch (CDbException $e) {
					PsSystemMessage::add('Commission structures not assigned', 'error');
					$tx->rollback();
				}
			}
			$this->refresh();
		}

		$params = array(
			':current_user_id' => $user->id,
			':agency_id' => $agency->id
		);
		$sql = "SELECT id, username, name FROM `user` u WHERE id <> :current_user_id AND agency_id = :agency_id";
		$otherUsers = Yii::app()->db->createCommand($sql)->query($params);

		$otherUsersListData = array();
		if (!empty($otherUsers)) {
			foreach ($otherUsers as $otherUser) {
				$otherUsersListData[$otherUser['id']] = '[' . $otherUser['username'] . '] ' . $otherUser['name'];
			}
		}

		$data = array();
		$data['user'] = $user;
		$data['promotionsDataProvider'] = $promotionsDataProvider;
		$data['scoreAdjustmentsDataProvider'] = $scoreAdjustmentsDataProvider;
		$data['parentStructures'] = $parentStructures;
		$data['ownStructures'] = $ownStructures;
		$data['assignedStructureIds'] = $assignedStructureIds;
		$data['authManager'] = $authManager;
		$data['otherUsersListData'] = $otherUsersListData;

		$this->render('commission', $data);
	}

	public function actionBankinfo($id)
	{
		$user = $this->loadUser($id);

		if (isset($_POST['User'])) {
			$user->setScenario('updateprofile');
			$user->attributes = $_POST['User'];

			$attributes = array(
				'bank_name',
				'bank_code',
				'bank_branch',
				'bank_branch_code',
				'bank_account_name',
				'bank_account_no',
				'bank_owner_address',
				'bank_owner_contact',
			);

			if ($user->validate($attributes)) {
				// Save user model
				if ($user->saveNode(false)) {
					PsSystemMessage::add('Bank Information Updated.', 'success');
					$this->refresh();
				} else {
					PsSystemMessage::add('There was a problem updating your profile. Please try again', 'error');
				}
			}
		}

		$this->render('bankinfo', array('user' => $user));
	}

	public function sendNotificationEmail($id)
	{
		$user = $this->loadUser($id);

		$tokenList = array();
		$tokenList["userFullname"] = $user->name;
		$tokenList["userMobile"] = $user->mobile;
		$tokenList["userEmail"] = $user->email;
		$tokenList["userNRIC"] = $user->nric;
		$tokenList["userLicenseNo"] = $user->license_no;
		$tokenList["agencyName"] = $user->agency->name;

		$subject = "Your profile has been updated.";

		$mailer = new Mailer();
		$mailer->layout = Yii::getPathOfAlias('common') . "/templates/emails/layouts/default.tpl";
		$mailer->addSender(Yii::app()->params["noreplyEmail"], Yii::app()->params["noreplyName"]);
		$mailer->addRecipient($user->email, $user->name);
		$mailer->addSubject($subject);

		$mailer->createHTMLMail(Yii::getPathOfAlias('common') . "/templates/emails/account/html/acctUpdateProfile.tpl", $tokenList);
		$mailer->createTEXTMail(Yii::getPathOfAlias('common') . "/templates/emails/account/text/acctUpdateProfile.tpl", $tokenList);

		$mailer->sendMail();
	}

	public function actionResetpw($id, $confirm = '')
	{
		$user = $this->loadModel($id, 'User');

		if ($confirm != '') {
			$resetPasswordOnly = true;

			$user->setScenario('manualactivate');
			$randomPassword = UserSecurityHelper::randomPassword(6);

			$user->password = $randomPassword;
			if ($user->status != User::STATUS_ACTIVE) {
				// activate account
				$user->status = User::STATUS_ACTIVE;

				if ($user->activate_date == null) {
					$user->activate_date = new CDbExpression('UTC_TIMESTAMP()');
				}

				$resetPasswordOnly = false;
			}

			if ($user->saveNode()) {
				if ($_POST["sendEmail"] == '1') {
					// send welcome email
					if ($resetPasswordOnly) {
						if ($user->sendResetPasswordEmail($randomPassword)) {
							PsSystemMessage::add('Reset Pasword email sent to ' . $user->email . '.', 'success');
						}
					} else {
						if ($user->sendAgencyWelcomeEmail($randomPassword)) {
							PsSystemMessage::add('Welcome email sent to ' . $user->email . '.', 'success');
						}
					}

					$user->sendActivationNotificationToAdmin();
				}
				if ($_POST["sendSMS"] == '1') {
					// send welcome sms
					if ($resetPasswordOnly) {
						if ($user->sendResetPasswordSMS($randomPassword)) {
							PsSystemMessage::add('Reset Pasword sms sent to ' . $user->mobile . '.', 'success');
						}
					} else {
						if ($user->sendAgencyWelcomeSMS($randomPassword)) {
							PsSystemMessage::add('Welcome sms sent to ' . $user->mobile . '.', 'success');
						}
					}
				}

				$this->render('resetpw', array(
					'user' => $user,
					'randomPassword' => $randomPassword
				));
			} else {
//				dump($user->getErrors());
			}
		} else {
			$this->render('resetpw', array(
				'user' => $user
			));
		}
	}

	public function actionAjaxSearchCEADatabase($license_no)
	{
		$response = array();

//        $user = PsCEADataGrabber::grabAgent($license_no);
		$user = User::model()->findByAttributes(array('license_no' => $license_no));
		if ($user === null) {
			$response['result'] = 'failure';
			$response['errorMsg'] = 'Salesperson not found';
		} else if ($user === PsCEADataGrabber::ERROR_GENERAL_EXCEPTION) {
			$response['result'] = 'failure';
			$response['errorMsg'] = 'Unable to access the CEA database temporarily. Please try again later.';
		} else if ($user instanceof User) {

			if ($user->agency_id != Yii::app()->user->getSelectedAgencyId()) {
				$response['result'] = 'failure';
				$response['errorMsg'] = 'User does not belong to ' . Yii::app()->user->getSelectedAgency()->name;
			} else {
				$response['result'] = 'success';
				$response['data'] = array(
					'license_no' => $user->license_no,
					'username' => $user->username,
					'name' => $user->name,
				);
			}
		}

		print json_encode($response);
	}

	public function getAgencyListData()
	{
		$currentAgency = Yii::app()->user->model->agency;

		$listData = array();

		$listData[$currentAgency->id] = '[' . $currentAgency->type . '] ' . $currentAgency->name;

		if ($currentAgency->hasChildAgencies()) {
			foreach ($currentAgency->getChildAgencies() as $childAgency) {
				$listData[$childAgency->id] = '[' . $childAgency->type . '] ' . $childAgency->name;
			}
		}

		return $listData;
	}

	public function loadUser($id)
	{
		$user = User::model()->ofCurrentAgency()->findByPk($id);

		if ($user == null) {
			$this->redirect(array('index'));
		}

		return $user;
	}

	public function actionTraininginfo($id)
	{
		$user = $this->loadUser($id);
		$trainingRecord = $user->activeTrainingRecord;


		if (is_null($trainingRecord)) {
			$trainingRecord = new UserTrainingRecord();
		}

		if (isset($_POST['User'])) {
			$isValid = true;
			$user->attributes = $_POST['User'];

			$attributes = array(
				'training_mode',
			);
			$isValid = $user->validate($attributes);

			if ($user->training_mode == 1) {
				$trainingRecord->user_id = $user->id;
				$isValid = $trainingRecord->validate();
			} else {
				$trainingRecord->status = 0;
				$trainingRecord->end_time = new CDbExpression('UTC_TIMESTAMP()');
				$isValid = $trainingRecord->validate();
			}

			if ($isValid) {
				// Save user model
				if ($user->saveNode(false)) {
					$trainingRecord->save();
					PsSystemMessage::add('User Traning Information Updated.', 'success');
					$this->refresh();
				} else {
					PsSystemMessage::add('There was a problem updating your training infor. Please try again', 'error');
				}
			}
		}

		$data = array();
		$data['user'] = $user;
		$data['trainingRecord'] = $trainingRecord;
		$data['trainingRecordsDataProvider'] = $this->getTrainingRecordDataProvider($user);

		$this->render('traininginfo', $data);
	}

	public function getTrainingRecordDataProvider(User $user, $pagesize = 50)
	{
		$criteria = new CDbCriteria;

		$criteria->compare('t.user_id', $user->id);
		$criteria->compare('t.deleted', 0);


		$sort = new CSort();
		$sort->defaultOrder = 't.start_time ASC';

		$dataProvider = new CActiveDataProvider('UserTrainingRecord', array(
					'criteria' => $criteria,
					'pagination' => array(
						'pageSize' => $pagesize,
					),
					'sort' => $sort
				));

		return $dataProvider;
	}

	public function actionAjaxDeletePromotion()
	{
		$response = array();

		if (isset($_POST['id'], $_POST['delete_reason'])) {
			$id = $_POST['id'];
			$deleteReason = $_POST['delete_reason'];

			$record = Promotion::model()->findByPk($id);

			if (!empty($record)) {
				$record->delete_reason = $deleteReason;
				$record->deleted_by_user_id = Yii::app()->user->id;
				$record->delete_time = new CDbExpression('UTC_TIMESTAMP()');
				$record->deleted = 1;

				if ($record->save()) {
					$response['result'] = 'success';
					$response['model'] = 'Promotion';
				}
			} else {
				$response['result'] = 'failure';
				$response['errorMsg'] = 'Record not found';
			}
		}

		print json_encode($response);
	}
	
	public function actionAjaxDeleteScoreAdjustement()
	{
		$response = array();

		if (isset($_POST['id'], $_POST['delete_reason'])) {
			$id = $_POST['id'];
			$deleteReason = $_POST['delete_reason'];

			$record = ScoreAdjustment::model()->findByPk($id);

			if (!empty($record)) {
				$record->delete_reason = $deleteReason;
				$record->deleted_by_user_id = Yii::app()->user->id;
				$record->delete_time = new CDbExpression('UTC_TIMESTAMP()');
				$record->deleted = 1;

				if ($record->save()) {
					$response['result'] = 'success';
					$response['model'] = 'ScoreAdjustment';
				}
			} else {
				$response['result'] = 'failure';
				$response['errorMsg'] = 'Record not found';
			}
		}

		print json_encode($response);
	}

}

?>
